本期精读文章 [CSS Animations vs Web Animations API | CSS-Tricks](https://css-tricks.com/css-animations-vs-web-animations-api/) 译文地址 [CSS Animation 与 Web Animation API 之争](https://zhuanlan.zhihu.com/p/27867539?refer=FrontendMagazine) # 1. 引言 logo 前端是一个很神奇的工种,一个合格的前端至少要熟练的使用 3 个技能,html、css 和 javascript。在传统的前端开发领域它们三个大多时候是各司其职,分别负责布局、样式以及交互。而在当代的前端开发中,由于多种原因 javascript 做的事情愈来愈多,大有一统全栈之势。服务端的 nodejs,让前端同学可以用自己的语言来开发 server。即便是在前端,我们现在好像也很少写 html 了,在 React 中出来了 JSX,在其他的开发体系中也有与之类似的前端模板代替了 html。我们好像也很少写 css 了,sass、less、stylus 等预处理器以及 css in js 出现。此外,很多 css 领域的的工作也可以通过 javascript 以更加优雅和高效的方式实现。今天我们来一起聊聊 CSS 动画与 WEB Animation API 的优劣。 # 2. 内容概要 JavaScript 规范确实借鉴了很多社区内的优秀类库,通过原生实现的方式提供更好的性能。WAAPI 提供了与 jQuery 类似的语法,同时也做了很多补充,使得其更加的强大。同时 W3C 官方也为开发者提供了 [web-animations/web-animations-js](https://github.com/web-animations/web-animations-js/tree/master) polyfill。下面简单回顾下文章内容: WAAPI 提供了很简洁明了的,我们可以直接在 dom 元素上直接调用 animate 函数: ```javascript var element = document.querySelector('.animate-me'); var animation = element.animate(keyframes, 1000); ``` 第一个参数是一个对象数组,每个对象表示动画中的一帧: ```javascript var keyframes = [ { opacity: 0 }, { opacity: 1 } ]; ``` 这与 css 中的 keyframe 定义类似: ```css 0% { opacity: 0; } 100% { opacity: 1; } ``` 第二个参数是 duration,表示动画的时间。同时也支持在第二个参数中传入配置项来指定缓动方式、循环次数等。 ```javascript var options = { iterations: Infinity, // 动画的重复次数,默认是 1 iterationStart: 0, // 用于指定动画开始的节点,默认是 0 delay: 0, // 动画延迟开始的毫秒数,默认 0 endDelay: 0, // 动画结束后延迟的毫秒数,默认 0 direction: 'alternate', // 动画的方向 默认是按照一个方向的动画,alternate 则表示交替 duration: 700, // 动画持续时间,默认 0 fill: 'forwards', // 是否在动画结束时回到元素开始动画前的状态 easing: 'ease-out', // 缓动方式,默认 "linear" }; ``` 有了这些配置项,基本可以满足开发者的动画需求。同时,文中也提到了在 WAAPI 中很多专业术语与 CSS 变量有所不同,不过这些变化也更显简洁。 在 dom 元素上调用 animate 函数之后返回 animation 对象,或者通过 ele.getAnimation 方法获取 dom 上的 animation 对象。借此开发者可以通过 promise 和 event 两种方式对动画进行操作: ## 1. event 方式 ```javascript myAnimation.onfinish = function() { element.remove(); } ``` ## 2. promise 方式 ```javascript myAnimation.finished.then(() => element.remove()) ``` 通过这种方式相对 dom 事件获取更加的简洁优雅。 # 3. 精读 参与本次精度的同学主要来自 [前端外刊评论 - 知乎专栏](https://zhuanlan.zhihu.com/FrontendMagazine) 的留言,该部分主要由文章评论总结而出。 ## WAAPI 优雅简洁 web animation 的 api 设计优雅而又全面。文中比对了常见的 WAAPI 与 CSS Animation 对照关系,我们可以看到 WAAPI 更加简洁,而且语法上也更加容易为开发者接受。确实,在写一些复杂的动画逻辑时,需要灵活控制性强的接口。我们可以看到,在处理串连多个动画、截取完整动画的一部分时更加方便。如果非要说有什么劣势,个人在开发中感觉 keyframe 的很多只都只能使用字符串,不过这也是将 css 写在 js 中最常见的一种方式了。 ## 低耦合 CSS 动画中,如果需要控制动画或者过渡的开始或结束只能通过相应的 dom 事件来监听,并且在回调函数中操作,这也是受 CSS 本身语言特性约束所致。也就是说很多情况下,想要完成一个动画需要结合 CSS 和 JS 来共同完成。使用 WAAPI 则有 promise 和 event 两种方式与监听 dom 事件相对应。从代码可维护性和完整性上看 WAAPI 有自身语言上的优势。 ## 兼容性和流畅度 兼容性上 WAAPI 常用方法已经兼容了大部分现代的浏览器。如果想现在就玩玩 WAAPI,可以使用官方提供的 polyfill。而 CSS 动画我们也用了很久,基本作为一种在现代浏览器中提升体验的方式,对于老旧的浏览器只能用一些优雅的降级方案。至于流畅度的问题,文中也提到性能与 CSS 动画一般,而且提供了性能优化的方案。 # 4. 总结 目前看来,CSS 动画可以做到的,使用 WAAPI 同样可以实现。至于浏览器支持问题,WAAPI 尚需要 polyfill 支持,不过 CSS 动画也同样存在兼容性问题。可能现在新的 API 的接受度还不够,但正如文章结尾处所说:『现有的规范和实现看起来更像是一项伟大事业的起点。』 > 讨论地址是:[精读《CSS Animations vs Web Animations API》 · Issue #22 · dt-fe/weekly](https://github.com/dt-fe/weekly/issues/22) > > 如果你想参与讨论,请[点击这里](https://github.com/dt-fe/weekly),每周都有新的主题,每周五发布。